package com.rc.saas.tenant.service.acct;

import com.rc.saas.tenant.mapper.acct.AcctRuleMapper;
import com.rc.saas.tenant.mapper.acct.AcctRuleRepositoryMapper;
import com.rc.saas.tenant.mapper.acct.AcctSubItemMapper;
import com.rc.saas.tenant.model.acct.*;
import com.rc.saas.tenant.service.operator.TenantOperatorStationService;
import com.rc.saas.tenant.vo.acct.AcctRuleRepositoryResultVo;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author frog
 * @date 2021/1/21
 */
@Service
public class AcctRuleRepositoryServiceImpl implements AcctRuleRepositoryService {

    @Autowired
    private AcctRuleRepositoryMapper acctRuleRepositoryMapper;
    @Autowired
    private AcctRuleMapper acctRuleMapper;

    @Autowired
    private TenantOperatorStationService tenantOperatorStationService;

    @Autowired
    private AcctSubItemMapper acctSubItemMapper;

    @Override
    public AcctRuleRepositoryMapper getMapper() {
        return acctRuleRepositoryMapper;
    }

    @Override
    public AcctRuleRepositoryResultVo listAcctRuleRepository(String tenantCode, Long acctRuleId,String ruleName) {
        AcctRuleRepositoryResultVo acctRuleRepositoryResultVo = new AcctRuleRepositoryResultVo();
        //模板
        //AcctRule acctRule = selectByOperatorStationId(operatorStationId);
        if (acctRuleId != null) {
            AcctRule acctRule = acctRuleMapper.selectByPrimaryKey(acctRuleId);
            acctRuleRepositoryResultVo.setElecAcctRule(acctRuleChangeList(acctRule.getElecAcctRule()));
            acctRuleRepositoryResultVo.setServiceAcctRule(acctRuleChangeList(acctRule.getServiceAcctRule()));
            //获取规则子项
            AcctSubItemExample example=new AcctSubItemExample();
            example.createCriteria().andAcctRuleIdEqualTo(acctRule.getAcctRuleId()).andTenantOperatorCodeEqualTo(acctRule.getTenantOperatorCode()).andOperatorStationIdEqualTo(acctRule.getOperatorStationId());
            List<AcctSubItem> subItems=acctSubItemMapper.selectByExample(example);
            if (subItems!=null&&subItems.size()>0){
                List<Map<String,List<String>>> acctSubItems=new LinkedList<>();
                for (AcctSubItem acctSubItem:subItems){
                    Map<String, List<String>> map = new HashMap<>();
                    map.put(acctSubItem.getSubItem() + "_" + acctSubItem.getSubItemId(), acctSubItemChangeList(acctSubItem.getSubItem()));
                    acctSubItems.add(map);
                }
                acctRuleRepositoryResultVo.setAcctSubItem(acctSubItems);
            }
        }
        //模板库
        List<AcctRuleRepository> acctRuleRepositories = listRepositoryByTenantCode(tenantCode,ruleName);
        LinkedList<Map<String, List<String>>> elecAcctRuleRepository = new LinkedList<>();
        LinkedList<Map<String, List<String>>> seviceAcctRuleRepository = new LinkedList<>();
        LinkedList<Map<String,List<String>>> acctSubItemRepository=new LinkedList<>();

        for (AcctRuleRepository acctRuleRepository : acctRuleRepositories) {
            Map<String, List<String>> map = new HashMap<>();
            if ("2".equals(acctRuleRepository.getRuleType())){
                map.put(acctRuleRepository.getRuleName() + "_" + acctRuleRepository.getRuleRepositoryId(), acctSubItemChangeList(acctRuleRepository.getAcctRule()));
            }else {
                map.put(acctRuleRepository.getRuleName() + "_" + acctRuleRepository.getRuleRepositoryId(), acctRuleChangeList(acctRuleRepository.getAcctRule()));
            }
            if ("0".equals(acctRuleRepository.getRuleType())) {
                elecAcctRuleRepository.add(map);
            } else if ("1".equals(acctRuleRepository.getRuleType())){
                seviceAcctRuleRepository.add(map);
            } else if ("2".equals(acctRuleRepository.getRuleType())){
                acctSubItemRepository.add(map);
            }
        }
        acctRuleRepositoryResultVo.setElecAcctRuleRepository(elecAcctRuleRepository);
        acctRuleRepositoryResultVo.setServiceAcctRuleRepository(seviceAcctRuleRepository);
        acctRuleRepositoryResultVo.setAcctSubItemRepository(acctSubItemRepository);
        return acctRuleRepositoryResultVo;
    }

    @Override
    public List<AcctRuleRepository> listRepositoryByTenantCode(String tenantCode,String ruleName) {
        return acctRuleRepositoryMapper.listRepositoryByTenantCode(tenantCode, ruleName);
//        AcctRuleRepositoryExample acctRuleRepositoryExample = new AcctRuleRepositoryExample();
//        if (ruleName!=null&&ruleName!=""){
//            acctRuleRepositoryExample.createCriteria().andTenantCodeEqualTo(tenantCode).andRuleNameLike(ruleName);
//        }else {
//            acctRuleRepositoryExample.createCriteria().andTenantCodeEqualTo(tenantCode);
//        }
//        List<AcctRuleRepository> acctRuleRepositories = acctRuleRepositoryMapper.selectByExample(acctRuleRepositoryExample);
//        return acctRuleRepositories;
    }

    @Override
    public AcctRule selectByOperatorStationId(Long operatorStationId) {
        Date date = new Date();
        AcctRuleExample acctRuleExample = new AcctRuleExample();
        acctRuleExample.createCriteria().andOperatorStationIdEqualTo(operatorStationId).andStatusEqualTo("0")
                .andRuleStartTimeLessThanOrEqualTo(date).andRuleEndTimeGreaterThanOrEqualTo(date);
        List<AcctRule> acctRules = acctRuleMapper.selectByExample(acctRuleExample);
        if (CollectionUtils.isEmpty(acctRules)) {
            return null;
        } else {
            return acctRules.get(0);
        }
    }

    List<String> acctRuleChangeList(String acctRule) {

        acctRule = acctRule.replace("平台服务费", "a");
        acctRule = acctRule.replace("平台电费", "b");
        acctRule = acctRule.replace("平台总金额", "c");
        acctRule = acctRule.replace("平台优惠金额", "d");
        acctRule = acctRule.replace("平台实收金额", "e");
        acctRule = acctRule.replace("平台电量", "f");
        acctRule = acctRule.replace("咨询订单金额", "g");

        String[] symbol = {"+", "-", "*", "/", "(", ")","="};
        String[] number = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."};

        List<String> symbolList = Arrays.asList(symbol);
        List<String> numberList = Arrays.asList(number);

        ArrayList<String> repositoryList = new ArrayList<>();

        StringBuilder numberSb = new StringBuilder();
        for (int i = 0; i < acctRule.length(); i++) {
            String element = String.valueOf(acctRule.charAt(i));
            if (symbolList.contains(element)) {
                //判断是否为符号

                //如果是"-"根据前一个字节判断是负号还是减号
                if ("-".equals(element)) {
                    if (i == 0) {
                        numberSb.append(element);
                    } else if ("(".equals(acctRule.charAt(i - 1))) {
                        numberSb.append(element);
                    } else if (")".equals(acctRule.charAt(i - 1))) {
                        repositoryList.add(element);
                    } else if (symbolList.contains(acctRule.charAt(i - 1)) && numberList.contains(acctRule.charAt(i + 1))) {
                        numberSb.append(element);
                    } else {
                        repositoryList.add(element);
                    }
                } else {
                    repositoryList.add(element);
                }
            } else if (element.matches("[a-zA-Z]+")) {
                repositoryList.add(element);
            } else if (numberList.contains(element)) {

                numberSb.append(element);

                if ((i + 1) >= acctRule.length()) {
                    repositoryList.add(numberSb.toString());
                } else {
                    String nextElement = String.valueOf(acctRule.charAt(i + 1));
                    //如果下一个是数字就拼接
                    if (!numberList.contains(nextElement)) {
                        repositoryList.add(numberSb.toString());
                        numberSb = new StringBuilder();
                    }
                }
            }
        }

        return repositoryList;
    }

    List<String> acctSubItemChangeList(String acctRule) {

        acctRule = acctRule.replace("平台服务费", "a");
        acctRule = acctRule.replace("平台电费", "b");
        acctRule = acctRule.replace("平台总金额", "c");
        acctRule = acctRule.replace("平台优惠金额", "d");
        acctRule = acctRule.replace("平台实收金额", "e");
        acctRule = acctRule.replace("平台电量", "f");
        acctRule = acctRule.replace("咨询订单金额", "g");

        String[] symbol = {"+", "-", "*", "/", "(", ")","="};
        String[] number = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."};

        List<String> symbolList = Arrays.asList(symbol);
        List<String> numberList = Arrays.asList(number);

        ArrayList<String> repositoryList = new ArrayList<>();

        StringBuilder numberSb = new StringBuilder();
        StringBuilder charSb=new StringBuilder();
        for (int i = 0; i < acctRule.length(); i++) {
            String element = String.valueOf(acctRule.charAt(i));
            if (symbolList.contains(element)) {
                //判断是否为符号
                //如果是"-"根据前一个字节判断是负号还是减号
                if ("-".equals(element)) {
                    if (i == 0) {
                        repositoryList.add("-");
                    }else if ("(".equals(acctRule.charAt(i - 1))) {
                        numberSb.append(element);
                    } else if (")".equals(acctRule.charAt(i - 1))) {
                        repositoryList.add(element);
                    } else if (symbolList.contains(acctRule.charAt(i - 1)) && numberList.contains(acctRule.charAt(i + 1))) {
                        numberSb.append(element);
                    } else {
                        repositoryList.add(element);
                    }
                } else {
                    repositoryList.add(element);
                }

            } else if (element.matches("[a-zA-Z]+")) {
                //字母
                repositoryList.add(element);
            } else if (numberList.contains(element)) {
                //数字
                numberSb.append(element);

                if ((i + 1) >= acctRule.length()) {
                    repositoryList.add(numberSb.toString());
                } else {
                    String nextElement = String.valueOf(acctRule.charAt(i + 1));
                    //如果下一个是数字就拼接
                    if (!numberList.contains(nextElement)) {
                        repositoryList.add(numberSb.toString());
                        numberSb = new StringBuilder();
                    }
                }
            } else {
                charSb.append(element);
                String nextElement = String.valueOf(acctRule.charAt(i + 1));
                if (symbolList.contains(nextElement)){
//                if ("=".equals(nextElement)){
                    repositoryList.add(charSb.toString());
                }else if (numberList.contains(nextElement)){
                    charSb.append(nextElement);
                    repositoryList.add(charSb.toString());
                    i=i+1;
                }
            }
        }

        return repositoryList;
    }
}
